package com.blvtphan.tipocketclubs.gui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;

import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.blvtphan.tipocketclubs.R;
import com.blvtphan.tipocketclubs.abstracts.AbstractActivity;
import com.blvtphan.tipocketclubs.api.ApiConstant;
import com.blvtphan.tipocketclubs.api.ApiHelper;
import com.blvtphan.tipocketclubs.custom.CustomButton;
import com.blvtphan.tipocketclubs.custom.CustomEditText;
import com.blvtphan.tipocketclubs.model.RewardsModel;
import com.blvtphan.tipocketclubs.system.UserSetting;
import com.blvtphan.tipocketclubs.util.ConnectionUtils;
import com.blvtphan.tipocketclubs.util.Constants;
import com.blvtphan.tipocketclubs.util.GeneralUtils;
import com.blvtphan.tipocketclubs.util.PreferenceUtils;
import com.blvtphan.tipocketclubs.widget.CustomAlertDialog;

public class QrCodeScannerActivity extends AbstractActivity{

	/* Variable */
	private Camera mCamera;
	private CameraPreview mPreview;
	private Handler autoFocusHandler;
	private ImageScanner scanner;
//	private boolean barcodeScanned = false;
	private boolean previewing = true;
	private CustomButton mBtnEnterCode;

	static {
		System.loadLibrary("iconv");
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Registering check Internet
//		ConnectionUtils.checkConnectInternet(mContext);
//		ConnectionUtils.registerCheckStateInternetConnection(mContext);
		
		// QR Code
		autoFocusHandler = new Handler();
		mCamera = getCameraInstance();
		
		/* Instance barcode scanner */
		scanner = new ImageScanner();
		scanner.setConfig(0, Config.X_DENSITY, 3);
		scanner.setConfig(0, Config.Y_DENSITY, 3);

		mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
		FrameLayout preview = (FrameLayout) findViewById(R.id.cameraPreview);
		preview.addView(mPreview);

	}

	/**
	 * 
	 */
	public void onPause() {
		super.onPause();
		releaseCamera();
	}

	/**
	 * A safe way to get an instance of the Camera object.
	 */
	public static Camera getCameraInstance() {
		Camera c = null;
		try {
			c = Camera.open();
		} catch (Exception e) {
		}
		return c;
	}

	/**
	 * releaseCamera
	 */
	private void releaseCamera() {
		if (mCamera != null) {
			previewing = false;
			mCamera.setPreviewCallback(null);
			mCamera.release();
			mCamera = null;
		}
	}

	/**
	 * Runnable doAutoFocus
	 */
	private Runnable doAutoFocus = new Runnable() {
		public void run() {
			if (previewing)
				mCamera.autoFocus(autoFocusCB);
		}
	};

	/**
	 * PreviewCallback previewCb
	 */
	PreviewCallback previewCb = new PreviewCallback() {
		public void onPreviewFrame(byte[] data, Camera camera) {
			Camera.Parameters parameters = camera.getParameters();
			Size size = parameters.getPreviewSize();

			Image barcode = new Image(size.width, size.height, "Y800");
			barcode.setData(data);

			int result = scanner.scanImage(barcode);

			if (result != 0) {
				previewing = false;
				mCamera.setPreviewCallback(null);
				mCamera.stopPreview();

				SymbolSet syms = scanner.getResults();
				for (Symbol sym : syms) {
					// scanText.setText("Barcode result: " + sym.getData());
//					Toast.makeText(mContext, sym.getData().toString(), Toast.LENGTH_SHORT).show();
					checkQRMerchantCode(sym.getData().toString());
//					barcodeScanned = true;
				}
			}
		}
	};
	
	/**
	 * checkQRMerchantCode
	 * @param code
	 */
	private void checkQRMerchantCode(String code) {
		String url = ApiHelper.genAPI(ApiConstant.API.API_POST_CHECK_MERCHANT_CODE);
		url = url.replace("{0}", UserSetting.getInstance().getToken());
		
		Map<String, String> params = new HashMap<String, String>();
		params.put("code", code);
		params.put("club_id", "6");

		List<NameValuePair> contents = PreferenceUtils
				.createHttpParams(params);
		
		ConnectionUtils.ExcuteHttpPostThread excuteHttpPost = new ConnectionUtils.ExcuteHttpPostThread(
				mContext, mProcessPostCheckMerchantCode, url, contents);
		excuteHttpPost.execute();
	}
	
	/**
	 * Handler mProcessPostCheckMerchantCode
	 */
	private Handler mProcessPostCheckMerchantCode = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case Constants.APIConstant.HANDLER_REQUEST_FAIL:
				// Connect fail
				GeneralUtils.showAlertDialog(mContext,
						mContext.getString(R.string.error_title),
						mContext.getString(R.string.mess_wrong_code));
				break;
			case Constants.APIConstant.HANDLER_REQUEST_SUCCESS:
				String result = (String) msg.obj;
				Log.i("QRCode", result);
				try {
					JSONObject obj = new JSONObject(result);
					if (!obj.isNull(ApiConstant.JsonType.DATA)) {
						// Set userId
						String merchantName = "", merchantId = "";
						List<RewardsModel> lstRewards = new ArrayList<RewardsModel>();
						
						JSONObject dataObj = obj.getJSONObject(ApiConstant.JsonType.DATA);
						if(!dataObj.isNull(ApiConstant.CheckMerchantCodeData.NAME))
							merchantName = dataObj.getString(ApiConstant.CheckMerchantCodeData.NAME);
						if(!dataObj.isNull(ApiConstant.CheckMerchantCodeData.ID))
							merchantId = dataObj.getString(ApiConstant.CheckMerchantCodeData.ID);
						JSONArray arrReward = dataObj.getJSONArray(ApiConstant.CheckMerchantCodeData.REWARDS);
						for(int i=0;i<arrReward.length();i++) {
							RewardsModel rewardsItem = new RewardsModel();
							JSONObject rewardObj = arrReward.getJSONObject(i);
							String id="", title="", discount="", type="", rewardMerchantId="", 
									fromDate="", toDate="", fromTime="", toTime="";
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.ID))
								id = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.ID);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.TITLE))
								title = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.TITLE);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.DISCOUNT))
								discount = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.DISCOUNT);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.TYPE))
								type = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.TYPE);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.FROM_DATE))
								fromDate = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.FROM_DATE);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.TO_DATE))
								toDate = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.TO_DATE);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.FROM_TIME))
								fromTime = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.FROM_TIME);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.TO_TIME))
								toTime = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.TO_TIME);
							if(!rewardObj.isNull(ApiConstant.CheckMerchantCodeRewards.MERCHANT_ID))
								rewardMerchantId = rewardObj.getString(ApiConstant.CheckMerchantCodeRewards.MERCHANT_ID);
							rewardsItem.setDiscount(discount);
							rewardsItem.setId(id);
							rewardsItem.setTitle(title);
							rewardsItem.setFromDate(fromDate);
							rewardsItem.setFromTime(fromTime);
							rewardsItem.setToDate(toDate);
							rewardsItem.setToTime(toTime);
							rewardsItem.setType(type);
							rewardsItem.setMerchantId(rewardMerchantId);
							lstRewards.add(rewardsItem);
						}
						
						// Go to main page
						Intent intent = new Intent(mContext, VerifyTrackActivity.class);
						intent.putExtra(Constants.CheckMerchantCodeExtras.MERCHANT_ID, merchantId);
						intent.putExtra(Constants.CheckMerchantCodeExtras.MERCHANT_NAME, merchantName);
						try {
							intent.putExtra(
									Constants.CheckMerchantCodeExtras.LIST_REWARDS,
									GeneralUtils.object2Bytes(lstRewards));
						} catch (IOException e) {
							e.printStackTrace();
						}
						startActivity(intent);
						finish();
					} else {
						
					}
				} catch (JSONException e) {
					e.printStackTrace();
					// Wrong
					GeneralUtils.showAlertDialog(mContext,
							mContext.getString(R.string.error_title),
							mContext.getString(R.string.mess_wrong_code));
				}
				break;
			default:
				break;
			}
		}
	};

	// Mimic continuous auto-focusing
	AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
		public void onAutoFocus(boolean success, Camera camera) {
			autoFocusHandler.postDelayed(doAutoFocus, 1000);
		}
	};

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);

		// Checks the orientation of the screen for landscape and portrait
		if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
			Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
		} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
			Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * Handler submit qrcode
	 */
	private Handler mProcessSubmitQrCode = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case Constants.APIConstant.HANDLER_REQUEST_FAIL:
				// Connect fail
				GeneralUtils.showAlertDialog(mContext,
						mContext.getString(R.string.error_title),
						mContext.getString(R.string.msg_connect_servier_fail));
				break;
			case Constants.APIConstant.HANDLER_REQUEST_SUCCESS:
				String result = (String) msg.obj;

				break;
			default:
				break;
			}
		}
	};

	@Override
	public int getContentViewId() {
		return R.layout.activity_qr_code_canner;
	}

	@Override
	public void initView() {
		mBtnEnterCode = (CustomButton)findViewById(R.id.btn_enter_code);
		mBtnEnterCode.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				View enterView = LayoutInflater.from(mContext).inflate(R.layout.dialog_enter_code, null, true);
				final CustomEditText editCode = (CustomEditText)enterView.findViewById(R.id.edt_enter_code);
				final CustomAlertDialog dialog = new CustomAlertDialog(mContext, enterView);
				dialog.setButton(getResources().getString(R.string.btn_show), new OnClickListener() {
					
					@Override
					public void onClick(View v) {
						if(!editCode.getText().toString().equals("")) {
							checkQRMerchantCode(editCode.getText().toString());
//							barcodeScanned = true;
						} else {
							GeneralUtils.showToastMessage(mContext, getResources().getString(R.string.mess_enter_code), Toast.LENGTH_SHORT);
						}
					}
				});
				dialog.setButton2(getResources().getString(R.string.cancel_button), new OnClickListener() {
					
					@Override
					public void onClick(View v) {
						dialog.hideDialog();
					}
				});
				dialog.setTitle(getResources().getString(R.string.text_enter_code));
				dialog.showDialog();
			}
		});
	}

	@Override
	public String getTitleBarTitle() {
		return mContext.getString(R.string.title_qrcode_screen);
	}

}
